package com.zxy.config;

import com.zxy.bean.Color;
import com.zxy.bean.ColorFactoryBean;
import com.zxy.bean.Person;
import com.zxy.bean.Red;
import com.zxy.condition.LinuxCondition;
import com.zxy.condition.MyImportBeanDefinitionRegistrar;
import com.zxy.condition.MyImportSelector;
import com.zxy.condition.WindowsCondition;
import com.zxy.service.BookService;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.List;
@Conditional({WindowsCondition.class})
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
//@Import导入组件，id默认是组件的全类名
/**
 * 满足当前条件，这个类中的配置才会生效
 */
@Configuration
/**
 * @ComponentScan(value = "com.zxy")  value指定要扫描的包
 * includeFilters设置只扫描某些包
 * useDefaultFilters = false，useDefaultFilters默认为true会扫描所有包，
 * 要使用includeFilters设置只扫描某些包需要把useDefaultFilters设置为false
 */
@ComponentScan(value = "com.zxy"
//        ,includeFilters = {
//    @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
//    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {BookService.class}),
//        @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
//},useDefaultFilters = false
)
/**
 * FilterType.ANNOTATION 按照注解
 * FilterType.ASSIGNABLE_TYPE  按照给定的类型
 * FilterType.ASPECTJ 使用ASPECTJ表达式
 * FilterType.REGEX 使用正则指定
 * FilterType.CUSTOM 使用自定义规则
 */

public class MainConfig {

    /**
     * 默认时单实例的
     * ConfigurableBeanFactory.SCOPE_PROTOTYPE, prototype
     * ConfigurableBeanFactory.SCOPE_SINGLETON, singleton
     * org.springframework.web.context.WebApplicationContext.SCOPE_REQUEST,  request
     * org.springframework.web.context.WebApplicationContext.SCOPE_SESSION, value session
     *
     * prototype  多实例的  ioc容器启动并不会调用方法创建对象放在容器中
     *                      每次获取的时候才会调用用方法创建对象
     * singleton    单实例的（默认值）ioc容器启动会调用方法创建对象到ioc容器中
     * 以后每次获取就是直接从容器（map.get()）中拿
     *
     * request  同一次请求创建一个实例
     * session  同一个session创建一个实例
     *
     *
     * 懒加载
     *          单实例bean，默认在容器启动的时候创建对象；
     *          懒加载：容器启动不创建对象，第一次使用（获取）bean时创建对象，并初始化
     */
    @Scope
    @Lazy
    @Bean("person01")
    public Person person(){
        System.out.println("给容器中添加person");
        return new Person("lisi",20);
    }
    /**
     * @Conditional({Condition[]})：按照一定的条件进行判断，满足条件给容器中注册bean
     *
     * 如果系统时windows给容器注册bill gates
     * 是linux给容器注册linus
     */
    @Bean("bill")
    public Person person01(){
        return new Person("Bill Gates",62);
    }
    @Conditional({LinuxCondition.class})
    @Bean("linus")
    public Person person02(){
        return new Person("linus",48);
    }
    /**
     * 给容器中注册组件
     * 1） 包扫描+组件注解（@Controller/@Service/@Repository/@Component）
     * 2) @Bean[导入的第三方包里面的组件]
     * 3)   @Import [快速给容器导入一个组件]：
     * @Import [要导入到容器中的组件]：容器中就会自动注册这个组件 id默认是全类名
     *
     * MyImportSelector
     * MyImportBeanDefinitionRegistrar
     */

    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
}
